#ifndef __MPxManipulatorNode_h
#define __MPxManipulatorNode_h
//-
// ==========================================================================
// Copyright (C) 1995 - 2006 Autodesk, Inc., and/or its licensors.  All
// rights reserved.
//
// The coded instructions, statements, computer programs, and/or related
// material (collectively the "Data") in these files contain unpublished
// information proprietary to Autodesk, Inc. ("Autodesk") and/or its
// licensors,  which is protected by U.S. and Canadian federal copyright law
// and by international treaties.
//
// The Data may not be disclosed or distributed to third parties or be
// copied or duplicated, in whole or in part, without the prior written
// consent of Autodesk.
//
// The copyright notices in the Software and this entire statement,
// including the above license grant, this restriction and the following
// disclaimer, must be included in all copies of the Software, in whole
// or in part, and all derivative works of the Software, unless such copies
// or derivative works are solely in the form of machine-executable object
// code generated by a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
// OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE. IN NO
// EVENT WILL AUTODESK AND/OR ITS LICENSORS BE LIABLE FOR ANY LOST
// REVENUES, DATA, OR PROFITS, OR SPECIAL, DIRECT, INDIRECT, OR
// CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK AND/OR ITS LICENSORS HAS
// BEEN ADVISED OF THE POSSIBILITY OR PROBABILITY OF SUCH DAMAGES.
// ==========================================================================
//+
//
// CLASS:    MPxManipulatorNode
//
// ****************************************************************************

#if defined __cplusplus

// ****************************************************************************
// INCLUDED HEADER FILES
#include <maya/MPxNode.h>
#include <maya/MTypes.h>
#include <maya/MGLdefinitions.h>
#include <maya/M3dView.h>
#include <maya/MDagPath.h>
#include <maya/MPoint.h>

// ****************************************************************************
// CLASS DECLARATION (MPxManipulatorNode)

//! \ingroup OpenMayaUI MPx
//! \brief Base class for manipulator creation 
/*!
MPxManipulatorNode is the base class used for creating user-defined
manipulators. This class is derived from MPxNode since manipulators in
Maya are dependency nodes.

An MPxManipulatorNode should implement the following method:

\code
virtual void draw(M3dView &view, const MDagPath &path,M3dView::DisplayStyle style, M3dView::DisplayStatus status);
\endcode

Additionally, several of the following virtuals will need to be defined:
\code
virtual MStatus	doPress( M3dView& view );
virtual MStatus	doDrag( M3dView& view );
virtual MStatus	doRelease( M3dView& view );
\endcode

Implement the following method to properly support undo:
\code
virtual MStatus connectToDependNode(const MObject &dependNode);
\endcode

The draw() method is very important since drawing and picking are
done together.  The colorAndName() method should be called before
drawing a GL component that should be pickable. Several color methods
which return color indexes that Maya use are provided to allow
custom manipulators to have a similar look.

When drawing a GL pickable component, an active name must be set.
Use the glFirstHandle() to get this value from the base class.

A manipulator can be connected to a depend node instead of updating
a node attribute directly in one of the do*() methods.  To connect
to a depend node, you must:

\li Call add*Value() in the postConstructor() of the node
\li Call conectPlugToValue() in connectToDependNode()
\li Call set*Value() in one of the do*() virtuals

This class can work standalone or with MPxManipContainer.
*/
class OPENMAYAUI_EXPORT MPxManipulatorNode  : public MPxNode
{
public:
	MPxManipulatorNode();
	virtual ~MPxManipulatorNode();

	virtual MStatus connectToDependNode(const MObject &dependNode);

	virtual void draw(M3dView &view, const MDagPath &path,
				M3dView::DisplayStyle style, M3dView::DisplayStatus status);

	virtual MStatus	doPress( M3dView& view );
	virtual MStatus	doDrag( M3dView& view );
	virtual MStatus	doRelease( M3dView& view );

	MStatus finishAddingManips();

	MStatus	colorAndName( M3dView& view, MGLuint glName, bool glNameIsPickable, short colorIndex ) const;

	MStatus glFirstHandle( MGLuint &firstHandle );

	MStatus glActiveName( MGLuint &glName );

	MStatus mouseRay( MPoint& linePoint, MVector& lineDirection ) const;
	MStatus mouseRayWorld( MPoint& linePoint, MVector& lineDirection ) const;

	MStatus mousePosition( short& x_pos, short& y_pos );
	MStatus mouseDown( short& x_pos, short& y_pos );
	MStatus mouseUp( short& x_pos, short& y_pos );

	MStatus addDoubleValue( const MString& valueName, double defaultValue, int& valueIndex );
	MStatus addPointValue( const MString& valueName, const MPoint& defaultValue, int& valueIndex );
	MStatus addVectorValue( const MString& valueName, const MVector& defaultValue, int& valueIndex );

	MStatus setDoubleValue( int valueIndex, double value );
	MStatus setPointValue( int valueIndex, const MPoint& value );
	MStatus setVectorValue( int valueIndex, const MVector& value );

	MStatus getDoubleValue( int valueIndex, bool previousValue, double& value );
	MStatus getPointValue( int valueIndex, bool previousValue, MPoint& value );
	MStatus getVectorValue( int valueIndex, bool previousValue, MVector& value );

	MStatus connectPlugToValue( const MPlug& plug, int valueIndex, int& plugIndex );

	static MPxManipulatorNode* newManipulator(const MString &manipName,
											  MObject &manipObject,
											  MStatus *ReturnStatus = NULL);

	short mainColor();
	short xColor();
	short yColor();
	short zColor();
	short prevColor();
	short lineColor();
	short dimmedColor();
	short selectedColor();
	short labelColor();
	short labelBackgroundColor();

	//! Connected node, message attribute
	static MObject connectedNodes;

	// Internal method
	void *getInstancePtr();
	void setInstancePtr( void *ptr );

	static const char *className();

protected:
// No protected members

private:
	static void initialSetup();
};

#endif /* _cplusplus */
#endif /* MPxManipulatorNode */
